import random
import string

from cloudinary.models import CloudinaryField
from django.db import models
from django.utils import timezone

from user.models import User


# 社交关系模型
class UserRelationship(models.Model):
    """用户关注关系"""
    follower = models.ForeignKey(
        User,
        on_delete=models.CASCADE,
        related_name='following',
        verbose_name='关注者'
    )
    following = models.ForeignKey(
        User,
        on_delete=models.CASCADE,
        related_name='followers',
        verbose_name='被关注者'
    )
    created_at = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')

    class Meta:
        db_table = 'user_relationships'
        unique_together = ('follower', 'following')
        verbose_name = '用户关注关系'
        verbose_name_plural = '用户关注关系'


# 拉黑
class UserBlacklist(models.Model):
    """用户黑名单"""
    user = models.ForeignKey(
        User,
        on_delete=models.CASCADE,
        related_name='blacklist_entries',
        verbose_name='用户'
    )
    blocked_user = models.ForeignKey(
        User,
        on_delete=models.CASCADE,
        related_name='blocked_by_entries',
        verbose_name='被屏蔽用户'
    )
    created_at = models.DateTimeField(auto_now_add=True, verbose_name='屏蔽时间')

    class Meta:
        db_table = 'user_blacklist'
        unique_together = ('user', 'blocked_user')
        verbose_name = '用户黑名单'
        verbose_name_plural = '用户黑名单'

    def __str__(self):
        return f"{self.user.username} 屏蔽了 {self.blocked_user.username}"

# 活动核心模型
class ActivityCategory(models.Model):
    """活动分类"""
    name = models.CharField(max_length=50, unique=True, verbose_name='分类名称')
    description = models.TextField(blank=True, verbose_name='分类描述')
    icon = models.CharField(max_length=100, blank=True, verbose_name='图标')
    is_active = models.BooleanField(default=True, verbose_name='是否启用')
    created_at = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')

    class Meta:
        db_table = 'activity_categories'
        verbose_name = '活动分类'
        verbose_name_plural = '活动分类'

    def __str__(self):
        return self.name


class Activity(models.Model):
    STATUS_CHOICES = (
        ('draft', '草稿'),
        ('published', '已发布'),
        ('cancelled', '已取消'),
        ('completed', '已完成'),
    )

    title = models.CharField(max_length=200, verbose_name="活动标题")
    description = models.TextField(verbose_name="活动描述")
    category = models.ForeignKey(ActivityCategory, on_delete=models.CASCADE, verbose_name="活动分类")
    organizer = models.ForeignKey(User, on_delete=models.CASCADE, related_name='organized_activities',
                                  verbose_name="组织者")

    start_time = models.DateTimeField(verbose_name="开始时间")
    end_time = models.DateTimeField(verbose_name="结束时间")
    location_name = models.CharField(max_length=100, verbose_name="地点名称")
    address = models.TextField(verbose_name="详细地址")
    latitude = models.FloatField(verbose_name="纬度", blank=True, null=True)
    longitude = models.FloatField(verbose_name="经度", blank=True, null=True)

    max_participants = models.PositiveIntegerField(verbose_name="最大参与人数")
    current_participants = models.PositiveIntegerField(default=0, verbose_name="当前参与人数")

    image = CloudinaryField('image', folder='meetlocal/activities')
    highlights = models.TextField(verbose_name="活动亮点", help_text="每行一个亮点")
    schedule = models.TextField(verbose_name="行程安排", help_text="每行一个安排")
    notes = models.TextField(verbose_name="注意事项", help_text="每行一个注意事项")

    status = models.CharField(max_length=20, choices=STATUS_CHOICES, default='draft', verbose_name="状态")
    views = models.PositiveIntegerField(default=0, verbose_name="浏览数")
    shares = models.PositiveIntegerField(default=0, verbose_name="分享数")

    created_at = models.DateTimeField(auto_now_add=True, verbose_name="创建时间")
    updated_at = models.DateTimeField(auto_now=True, verbose_name="更新时间")

    def get_image_url(self):
        """安全获取图片URL的方法"""
        try:
            if self.image and hasattr(self.image, 'url'):
                return self.image.url
        except Exception:
            pass
        # 返回默认图片
        return '/static/images/default-activity.jpg'

    class Meta:
        verbose_name = "活动"
        verbose_name_plural = "活动"
        ordering = ['-created_at']

    @property
    def time_based_status(self):
        """
        基于时间计算的活动状态
        每个活动都会根据自身的开始和结束时间实时计算当前状态
        """
        now = timezone.now()

        # 如果活动已取消，直接返回cancelled
        if self.status == 'cancelled':
            return 'cancelled'

        # 如果活动是草稿状态
        if self.status == 'draft':
            return 'draft'

        # 基于时间判断
        if now < self.start_time:
            return 'upcoming'  # 即将开始
        elif self.start_time <= now <= self.end_time:
            return 'ongoing'  # 进行中
        else:
            # 如果结束时间已过，但状态还是published，可以自动更新为completed
            if self.status == 'published':
                # 注意：这里不自动保存，避免频繁的数据库写入
                # 可以在管理后台或定时任务中处理状态更新
                pass
            return 'ended'  # 已结束

    @property
    def status_display(self):
        """返回用于显示的状态文本"""
        status_map = {
            'upcoming': '即将开始',
            'ongoing': '进行中',
            'ended': '已结束',
            'cancelled': '已取消',
            'draft': '草稿'
        }
        return status_map.get(self.time_based_status, '未知状态')

    @property
    def can_join(self):
        """检查活动当前是否可以报名"""
        return (self.status == 'published' and
                self.time_based_status == 'upcoming' and
                not self.is_full())

    def get_status_class(self):
        """返回状态对应的CSS类名"""
        return self.time_based_status


    def is_activity_started(self):
        """检查活动是否已开始"""
        return self.start_time <= timezone.now()

    def is_user_joined(self, user):
        """检查用户是否已报名"""
        if not user.is_authenticated:
            return False
        return ActivityParticipation.objects.filter(
            user=user,
            activity=self,
            status__in=['registered', 'attended']
        ).exists()

    def can_user_join(self, user):
        """检查用户是否可以报名"""
        if not user.is_authenticated:
            return False, "请先登录"
        if user == self.organizer:
            return False, "不能报名自己组织的活动"
        if self.is_full():
            return False, "活动已满员"
        if self.is_activity_started():
            return False, "活动已开始，无法报名"
        if self.is_user_joined(user):
            return False, "您已经报名过此活动"
        return True, "可以报名"

    def __str__(self):
        return self.title

    def is_full(self):
        return self.current_participants >= self.max_participants

    def available_spots(self):
        return self.max_participants - self.current_participants


# 活动参与模型
class ActivityParticipation(models.Model):
    """活动参与记录"""
    STATUS_CHOICES = [
        ('registered', '已报名'),
        ('attended', '已参加'),
        ('cancelled', '已取消'),
        ('no_show', '未到场')
    ]

    user = models.ForeignKey(
        User,
        on_delete=models.CASCADE,
        related_name='participations',
        verbose_name='用户'
    )
    activity = models.ForeignKey(
        Activity,
        on_delete=models.CASCADE,
        related_name='participants',
        verbose_name='活动'
    )
    status = models.CharField(
        max_length=20,
        choices=STATUS_CHOICES,
        default='registered',
        verbose_name='参与状态'
    )
    joined_at = models.DateTimeField(auto_now_add=True, verbose_name='报名时间')
    updated_at = models.DateTimeField(auto_now=True, verbose_name='更新时间')

    class Meta:
        db_table = 'activity_participations'
        unique_together = ('user', 'activity')
        ordering = ['-joined_at']
        verbose_name = '活动参与'
        verbose_name_plural = '活动参与'


# 评论与评分模型
class ActivityReview(models.Model):
    """活动评论与评分"""
    RATING_CHOICES = [
        (1, '1星'),
        (2, '2星'),
        (3, '3星'),
        (4, '4星'),
        (5, '5星')
    ]

    user = models.ForeignKey(
        User,
        on_delete=models.CASCADE,
        related_name='reviews',
        verbose_name='用户'
    )
    activity = models.ForeignKey(
        Activity,
        on_delete=models.CASCADE,
        related_name='reviews',
        verbose_name='活动'
    )
    rating = models.PositiveSmallIntegerField(choices=RATING_CHOICES, verbose_name='评分')
    comment = models.TextField(verbose_name='评论内容')
    images = models.JSONField(default=list, blank=True, verbose_name='评论图片')
    is_verified = models.BooleanField(default=False, verbose_name='已验证参与')
    created_at = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
    updated_at = models.DateTimeField(auto_now=True, verbose_name='更新时间')

    class Meta:
        db_table = 'activity_reviews'
        unique_together = ('user', 'activity')
        ordering = ['-created_at']
        verbose_name = '活动评价'
        verbose_name_plural = '活动评价'


class ReviewReply(models.Model):
    """评论回复"""
    review = models.ForeignKey(
        ActivityReview,
        on_delete=models.CASCADE,
        related_name='replies',
        verbose_name='评价'
    )
    user = models.ForeignKey(
        User,
        on_delete=models.CASCADE,
        related_name='review_replies',
        verbose_name='用户'
    )
    content = models.TextField(verbose_name='回复内容')
    created_at = models.DateTimeField(auto_now_add=True, verbose_name='回复时间')

    class Meta:
        db_table = 'review_replies'
        ordering = ['created_at']
        verbose_name = '评价回复'
        verbose_name_plural = '评价回复'

    def __str__(self):
        return f"{self.user.username} 回复 {self.review.user.username}"

class ReviewLike(models.Model):
    """评论点赞"""
    user = models.ForeignKey(
        User,
        on_delete=models.CASCADE,
        related_name='review_likes',
        verbose_name='用户'
    )
    review = models.ForeignKey(
        ActivityReview,
        on_delete=models.CASCADE,
        related_name='likes',
        verbose_name='评价'
    )
    created_at = models.DateTimeField(auto_now_add=True, verbose_name='点赞时间')

    class Meta:
        db_table = 'review_likes'
        unique_together = ('user', 'review')
        verbose_name = '评价点赞'
        verbose_name_plural = '评价点赞'

class ReviewReplyLike(models.Model):
    """回复点赞"""
    user = models.ForeignKey(
        User,
        on_delete=models.CASCADE,
        related_name='review_reply_likes',
        verbose_name='用户'
    )
    reply = models.ForeignKey(
        ReviewReply,
        on_delete=models.CASCADE,
        related_name='likes',
        verbose_name='回复'
    )
    created_at = models.DateTimeField(auto_now_add=True, verbose_name='点赞时间')

    class Meta:
        db_table = 'review_reply_likes'
        unique_together = ('user', 'reply')
        verbose_name = '回复点赞'
        verbose_name_plural = '回复点赞'

# 浏览历史
class BrowsingHistory(models.Model):
    """用户浏览历史"""
    user = models.ForeignKey(
        User,
        on_delete=models.CASCADE,
        related_name='browsing_history',
        verbose_name='用户'
    )
    activity = models.ForeignKey(
        Activity,
        on_delete=models.CASCADE,
        related_name='browsing_history',
        verbose_name='活动'
    )
    viewed_at = models.DateTimeField(auto_now_add=True, verbose_name='浏览时间')

    class Meta:
        db_table = 'browsing_history'
        ordering = ['-viewed_at']
        verbose_name = '浏览历史'
        verbose_name_plural = '浏览历史'
        unique_together = ('user', 'activity')  # 同一用户对同一活动只记录一次，更新浏览时间

    def __str__(self):
        return f"{self.user.username} 浏览 {self.activity.title}"


# 社区
class ActivityDiscussion(models.Model):
    """活动讨论区"""
    activity = models.ForeignKey(
        Activity,
        on_delete=models.CASCADE,
        related_name='discussions',
        verbose_name='活动'
    )
    user = models.ForeignKey(
        User,
        on_delete=models.CASCADE,
        related_name='discussion_posts',
        verbose_name='用户'
    )
    content = models.TextField(verbose_name='讨论内容')
    like_count = models.PositiveIntegerField(default=0, verbose_name='点赞数')
    comment_count = models.PositiveIntegerField(default=0, verbose_name='评论数')
    shares_count = models.PositiveIntegerField(default=0, verbose_name='转发数')
    created_at = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
    updated_at = models.DateTimeField(auto_now=True, verbose_name='更新时间')

    class Meta:
        db_table = 'activity_discussions'
        ordering = ['-created_at']
        verbose_name = '活动讨论'
        verbose_name_plural = '活动讨论'

    def __str__(self):
        return f"{self.user.username} - {self.content[:20]}"

class DiscussionImage(models.Model):
    """讨论图片"""
    discussion = models.ForeignKey(
        ActivityDiscussion,
        on_delete=models.CASCADE,
        related_name='discussionimage_set',
        verbose_name='讨论'
    )
    image = models.ImageField(
        upload_to='discussion_images/%Y/%m/%d/',
        verbose_name='图片'
    )
    created_at = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')

    class Meta:
        db_table = 'discussion_images'
        ordering = ['created_at']
        verbose_name = '讨论图片'
        verbose_name_plural = '讨论图片'

    def __str__(self):
        return f"图片 - {self.discussion.content[:20]}"


class DiscussionComment(models.Model):
    """讨论评论"""
    discussion = models.ForeignKey(
        ActivityDiscussion,
        on_delete=models.CASCADE,
        related_name='comments',
        verbose_name='讨论'
    )
    user = models.ForeignKey(
        User,
        on_delete=models.CASCADE,
        related_name='discussion_comments',
        verbose_name='用户'
    )
    content = models.TextField(verbose_name='评论内容')
    parent_comment = models.ForeignKey(
        'self',
        on_delete=models.CASCADE,
        null=True,
        blank=True,
        related_name='replies',
        verbose_name='父评论'
    )
    created_at = models.DateTimeField(auto_now_add=True, verbose_name='评论时间')

    class Meta:
        db_table = 'discussion_comments'
        ordering = ['created_at']
        verbose_name = '讨论评论'
        verbose_name_plural = '讨论评论'


class DiscussionLike(models.Model):
    """讨论点赞"""
    user = models.ForeignKey(
        User,
        on_delete=models.CASCADE,
        related_name='discussion_likes',
        verbose_name='用户'
    )
    discussion = models.ForeignKey(
        ActivityDiscussion,
        on_delete=models.CASCADE,
        related_name='likes',
        verbose_name='讨论'
    )
    created_at = models.DateTimeField(auto_now_add=True, verbose_name='点赞时间')

    class Meta:
        db_table = 'discussion_likes'
        unique_together = ('user', 'discussion')
        verbose_name = '讨论点赞'
        verbose_name_plural = '讨论点赞'


class DiscussionFavorite(models.Model):
    """讨论收藏"""
    user = models.ForeignKey(
        User,
        on_delete=models.CASCADE,
        related_name='favorite_discussions',
        verbose_name='用户'
    )
    discussion = models.ForeignKey(
        ActivityDiscussion,
        on_delete=models.CASCADE,
        related_name='favorites',
        verbose_name='讨论'
    )
    created_at = models.DateTimeField(auto_now_add=True, verbose_name='收藏时间')

    class Meta:
        db_table = 'discussion_favorites'
        unique_together = ('user', 'discussion')
        verbose_name = '讨论收藏'
        verbose_name_plural = '讨论收藏'


class DiscussionShare(models.Model):
    """讨论分享/转发"""
    user = models.ForeignKey(
        User,
        on_delete=models.CASCADE,
        related_name='shared_discussions',
        verbose_name='用户'
    )
    discussion = models.ForeignKey(
        ActivityDiscussion,
        on_delete=models.CASCADE,
        related_name='shares',
        verbose_name='讨论'
    )
    created_at = models.DateTimeField(auto_now_add=True, verbose_name='转发时间')

    class Meta:
        db_table = 'discussion_shares'
        verbose_name = '讨论转发'
        verbose_name_plural = '讨论转发'


# 积分模型
class PointsHistory(models.Model):
    """积分历史记录"""
    POINTS_SOURCE_CHOICES = [
        ('activity_join', '参加活动'),
        ('activity_review', '活动评价'),
        ('discussion_post', '发布讨论'),
        ('discussion_comment', '讨论评论'),
        ('daily_signin', '每日签到'),
        ('points_exchange', '积分兑换'),
        ('admin_adjust', '管理员调整'),
        ('invite_friend', '邀请好友'),
    ]

    user = models.ForeignKey(
        User,
        on_delete=models.CASCADE,
        related_name='points_history',
        verbose_name='用户'
    )
    points = models.IntegerField(verbose_name='积分变化')  # 正数为获得，负数为消耗
    source_type = models.CharField(max_length=20, choices=POINTS_SOURCE_CHOICES, verbose_name='积分来源')
    source_id = models.CharField(max_length=100, blank=True, verbose_name='来源ID')
    description = models.CharField(max_length=200, verbose_name='描述')
    created_at = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')

    class Meta:
        db_table = 'points_history'
        ordering = ['-created_at']
        verbose_name = '积分历史'
        verbose_name_plural = '积分历史'

    def __str__(self):
        return f"{self.user.username} - {self.points}分 - {self.description}"


# ... 文件开头的导入和其他模型定义 ...

# 积分商品模型 - 必须先定义
class PointsProduct(models.Model):
    """积分商品"""
    STATUS_CHOICES = [
        ('active', '上架'),
        ('inactive', '下架'),
        ('sold_out', '售罄'),
    ]

    CATEGORY_CHOICES = [
        ('virtual', '虚拟商品'),
        ('physical', '实物商品'),
        ('coupon', '优惠券'),
    ]

    name = models.CharField(max_length=100, verbose_name='商品名称')
    description = models.TextField(verbose_name='商品描述')
    category = models.CharField(max_length=20, choices=CATEGORY_CHOICES, default='physical', verbose_name='商品类别')
    image = models.ImageField(upload_to='points_products/', verbose_name='商品图片')
    points_required = models.PositiveIntegerField(verbose_name='所需积分')
    stock = models.PositiveIntegerField(default=0, verbose_name='库存')
    original_price = models.DecimalField(max_digits=10, decimal_places=2, blank=True, null=True, verbose_name='原价')
    status = models.CharField(max_length=20, choices=STATUS_CHOICES, default='active', verbose_name='状态')
    sort_order = models.PositiveIntegerField(default=0, verbose_name='排序')
    exchange_count = models.PositiveIntegerField(default=0, verbose_name='兑换次数')
    created_at = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
    updated_at = models.DateTimeField(auto_now=True, verbose_name='更新时间')

    class Meta:
        db_table = 'points_products'
        ordering = ['sort_order', '-created_at']
        verbose_name = '积分商品'
        verbose_name_plural = '积分商品'

    def __str__(self):
        return self.name

    def get_status_display(self):
        """获取状态显示文本"""
        status_map = {
            'active': '上架',
            'inactive': '下架',
            'sold_out': '售罄'
        }
        return status_map.get(self.status, self.status)

    @property
    def can_exchange(self):
        """检查商品是否可以兑换"""
        return self.status == 'active' and self.stock > 0


# 积分兑换记录模型 - 在 PointsProduct 之后定义
class PointsExchange(models.Model):
    """积分兑换记录"""
    STATUS_CHOICES = [
        ('pending', '待处理'),
        ('shipped', '已发货'),
        ('completed', '已完成'),
        ('cancelled', '已取消'),
    ]

    user = models.ForeignKey(
        User,
        on_delete=models.CASCADE,
        related_name='points_exchanges',
        verbose_name='用户'
    )
    product = models.ForeignKey(
        'PointsProduct',  # 使用字符串引用而不是直接类名
        on_delete=models.CASCADE,
        related_name='exchanges',
        verbose_name='商品'
    )
    points_used = models.PositiveIntegerField(verbose_name='使用积分')
    status = models.CharField(max_length=20, choices=STATUS_CHOICES, default='pending', verbose_name='状态')
    shipping_address = models.TextField(blank=True, verbose_name='收货地址')
    contact_name = models.CharField(max_length=50, blank=True, verbose_name='联系人')
    contact_phone = models.CharField(max_length=20, blank=True, verbose_name='联系电话')
    tracking_number = models.CharField(max_length=100, blank=True, verbose_name='快递单号')
    exchange_code = models.CharField(max_length=20, blank=True, verbose_name='兑换码')  # 用于虚拟商品
    created_at = models.DateTimeField(auto_now_add=True, verbose_name='兑换时间')
    updated_at = models.DateTimeField(auto_now=True, verbose_name='更新时间')

    class Meta:
        db_table = 'points_exchanges'
        ordering = ['-created_at']
        verbose_name = '积分兑换'
        verbose_name_plural = '积分兑换'

    def __str__(self):
        return f"{self.user.username} - {self.product.name}"

    def save(self, *args, **kwargs):
        # 为虚拟商品自动生成兑换码
        if not self.exchange_code and hasattr(self, 'product') and self.product and self.product.category == 'virtual':
            self.exchange_code = ''.join(random.choices(string.ascii_uppercase + string.digits, k=12))
        super().save(*args, **kwargs)

    def get_status_display(self):
        """获取状态显示文本"""
        status_map = {
            'pending': '待处理',
            'shipped': '已发货',
            'completed': '已完成',
            'cancelled': '已取消'
        }
        return status_map.get(self.status, self.status)

# ... 文件的其他部分 ...


class DailySignIn(models.Model):
    """每日签到记录"""
    user = models.ForeignKey(
        User,
        on_delete=models.CASCADE,
        related_name='daily_signins',
        verbose_name='用户'
    )
    signin_date = models.DateField(verbose_name='签到日期')
    consecutive_days = models.PositiveIntegerField(default=1, verbose_name='连续签到天数')
    points_earned = models.PositiveIntegerField(default=0, verbose_name='获得积分')
    created_at = models.DateTimeField(auto_now_add=True, verbose_name='签到时间')

    class Meta:
        db_table = 'daily_signins'
        unique_together = ('user', 'signin_date')
        ordering = ['-signin_date']
        verbose_name = '每日签到'
        verbose_name_plural = '每日签到'

    def __str__(self):
        return f"{self.user.username} - {self.signin_date}"


class PointsRule(models.Model):
    """积分规则配置"""
    name = models.CharField(max_length=100, verbose_name='规则名称')
    action = models.CharField(max_length=50, unique=True, verbose_name='动作标识')
    points = models.IntegerField(verbose_name='积分值')
    daily_limit = models.PositiveIntegerField(default=0, verbose_name='每日上限')
    description = models.TextField(verbose_name='规则描述')
    is_active = models.BooleanField(default=True, verbose_name='是否启用')
    created_at = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')

    class Meta:
        db_table = 'points_rules'
        verbose_name = '积分规则'
        verbose_name_plural = '积分规则'

    def __str__(self):
        return self.name

